<!-- eslint-disable vue/no-parsing-error -->
<template>
  <div class="app-container">
    <el-steps :active="active" finish-status="success" align-center>
      <el-step
        v-for="(i, f) in stepsTitle"
        :key="f"
        :title="f == active ? '进行中' : i.title"
        :description="f == active ? 'in progress' : i.description"
        @click.native="handleClickStep(f)"
      />
    </el-steps>
    <div class="main">
      <StepsOne v-if="active == 0" ref="submitOneForm" :data="form" />
      <StepsTwo v-if="active == 1" ref="submitTwoForm" :data="form" />
      <StepsThree v-if="active == 2" ref="submitThreeForm" :data="form" />
      <StepsFour v-if="active == 3" ref="submitFourForm" :data="form" />
      <StepsFive v-if="active == 4" ref="submitFiveForm" :data="form" />
    </div>
    <div class="buttonBox">
      <el-button
        v-if="active > 0"
        size="medium"
        @click.prevent="handleClick('prev')"
      >上一步</el-button>
      <el-button
        type="primary"
        size="medium"
        @click.prevent="handleClick('next')"
      >{{ active < stepsTitle.length - 1 ? "下一步" : "完成" }}</el-button>
    </div>
  </div>
</template>

<script>
import { convertToCamelCase } from '@/utils/index.js'
import StepsOne from './components/stepsOne.vue'
import StepsTwo from './components/stepsTwo.vue'
import StepsThree from './components/stepsThree.vue'
import StepsFour from './components/stepsFour.vue'
import StepsFive from './components/stepsFive.vue'

import { dataTaskconfadd, dataTaskconfedit } from '@/api/console/tasks.js'

import { getDataTaskconf } from '@/api/console/dataTaskconf.js'

const refsArray = [
  'submitOneForm',
  'submitTwoForm',
  'submitThreeForm',
  'submitFourForm',
  'submitFiveForm'
]
const removeValue = [
  'ip',
  'pwd',
  'port',
  'uname',
  'start',
  'end',
  'baseType',
  'appraiseCountmode',
  'appraiseTaskmode',
  'cdcSwitch',
  'jobSwitch'
]
export default {
  name: 'Steps',
  components: { StepsOne, StepsTwo, StepsThree, StepsFour, StepsFive },
  data() {
    return {
      active: 0,
      stepsTitle: [
        {
          title: '基本信息',
          description: '请基本信息'
        },
        {
          title: '选择数据源',
          description: '请选择起始源和目标源'
        },
        {
          title: '任务选择',
          description: '选择需要执行的参数表'
        },
        {
          title: '配置参数',
          description: '选择同步所需配置'
        },
        {
          title: '同步配置预览',
          description: '同步任务配置汇总预览'
        }
      ],
      totalData: {},
      id: null,
      form: {
        status: null
      }
    }
  },
  computed: {},
  dicts: [
    'data_base_type',
    'synchronous_tasktype',
    'data_sync_writebatch',
    'synchronous_exceptionhandling',
    'synchronous_jobmode'
  ],
  created() {
    const that = this
    this.$route.meta.title = this.$route.query.id
      ? '修改迁移任务'
      : '新增迁移任务'
    if (that.$route.query.id) {
      const newMapping = []
      that.id = that.$route.query.id
      getDataTaskconf({ id: that.$route.query.id }).then(async({ data }) => {
        data.taskTypeScope = data.taskTypeScope.split(',')
        data.mapping = JSON.parse(data.mapping)
        if (data.mapping) {
          Object.keys(data.mapping).forEach((f, i) => {
            if (data.mapping[f].length > 0) {
              newMapping.push(...data.mapping[f])
            }
          })
          data.mapping = newMapping
        }
        data.strategy = String(data.strategy)
        data.start = data.taskType.split('-')[0]
        data.end = data.taskType.split('-')[1]
        data.monitorConf = data.monitorConf ? JSON.parse(data.monitorConf) : {}
        data.syncConf = data.syncConf ? JSON.parse(data.syncConf) : {}
        data.syncStatus = !(data.syncStatus == '0')
        data.mappingStatus = !(data.mappingStatus == '0')
        data.monitorStatus = !(data.monitorStatus == '0')
        data.batchStatus = !(data.batchStatus == '0')
        data.typeStatus = !(data.typeStatus == '0')
        if (data.tableTypeMapping) {
          const arr = []
          JSON.parse(data.tableTypeMapping).forEach((f) => {
            arr.push({
              sink: {
                name: f.sink.name,
                table: f.sink.table,
                ...f.sink.dataType
              },
              source: {
                name: f.source.name,
                table: f.source.table,
                ...f.source.dataType
              }
            })
          })
          data.tableTypeMapping = arr
        }
        if (data.dbTypeMapping) {
          data.dbTypeMapping = JSON.parse(data.dbTypeMapping)
        }
        if (data.syncConf) {
          const obj = {}
          Object.keys(data.syncConf).forEach((f) => {
            const newValue = convertToCamelCase(f)
            obj[newValue] = data.syncConf[f]
            delete data.syncConf[f]
          })
          data.syncConf = obj
        }
        that.form = data
      })
    }
  },
  mounted() {
    const that = this
    setTimeout(() => {
      if (!this.$route.query.id) {
        setTimeout(() => {
          this.form = {
            status: '0',
            jobType: ['common', that.dict.type.synchronous_tasktype[0].value],
            readerBatch: that.dict.type.data_sync_writebatch[0].value,
            taskPolicy: this.dict.type.synchronous_exceptionhandling[0].value,
            jobMode: this.dict.type.synchronous_jobmode[0].value,
            start: 'MYSQL',
            end: 'DAMENG'
          }
        }, 1000)
      } else {
        this.getDicts('synchronous_tasktype').then((res) => {
          const item = res.data.find((f) => f.dictValue === that.form.jobType)
          if (item) {
            that.form.jobType = [
              item.remark === 'common' ? 'common' : 'basic',
              that.form.jobType
            ]
          }
        })
      }
    }, 100)
  },
  methods: {
    toSnakeCase(camelCaseStr, char) {
      return camelCaseStr
        .replace(/([a-z])([A-Z])/g, `$1${char}$2`)
        .toLowerCase()
    },
    handleClick(status) {
      const that = this
      const leg = that.stepsTitle.length - 1
      const fun = {
        next() {
          if (that.active === 4) {
            that.dataFusion(that.form)
            return
          }
          if (that.active++ > leg) that.active = leg
        },
        prev() {
          if (that.active-- < 0) that.active = leg
        }
      }
      if (status === 'next' && this.$refs[refsArray[this.active]].$refs.form) {
        this.$refs[refsArray[this.active]].$refs.form.validate((valid) => {
          if (valid) {
            fun[status]()
            return
          }
        })
        return
      }
      if (
        status === 'next' &&
        this.active === 3 &&
        this.form.jobMode === 'STREAMING' &&
        (!this.form.syncStatus || JSON.stringify(this.form.syncConf) === '{}')
      ) {
        this.$message.warning('请填写同步配置')
        return
      }
      fun[status]()
      return false
    },
    async dataFusion(form) {
      const data = JSON.parse(JSON.stringify(form))
      data.taskTables = JSON.stringify([])
      data.monitorConf = data.monitorStatus
        ? JSON.stringify(data.monitorConf)
        : '{}'
      data.syncConf = data.syncStatus ? JSON.stringify(data.syncConf) : '{}'
      data.taskType = `${data.start}-${data.end}`
      data.syncStatus = data.syncStatus ? 1 : 0
      data.monitorStatus = data.monitorStatus ? 1 : 0
      data.batchStatus = data.batchStatus ? 1 : 0
      data.mappingStatus = data.mappingStatus ? 1 : 0
      data.typeStatus = data.typeStatus ? 1 : 0
      if (data.dbTypeMapping) {
        data.dbTypeMapping.forEach((f) => {
          delete f.levae
        })
        data.dbTypeMapping = JSON.stringify(data.dbTypeMapping)
      }
      if (data.tableTypeMapping) {
        const typeMapping = []
        data.tableTypeMapping.forEach((f) => {
          // delete f.levae;
          typeMapping.push({
            source: {
              table: f.source.table,
              name: f.source.table,
              dataType: {
                typeName: f.source.typeName,
                length: f.source.length,
                precision: f.source.precision,
                scale: f.source.scale,
                timePrecision: f.source.timePrecision,
                nullable: f.sink.nullable
              }
            },
            sink: {
              table: f.sink.table,
              name: f.sink.table,
              dataType: {
                typeName: f.sink.typeName,
                length: f.sink.length,
                precision: f.sink.precision,
                scale: f.sink.scale,
                timePrecision: f.sink.timePrecision,
                nullable: f.sink.nullable
              }
            }
          })
        })
        data.tableTypeMapping = JSON.stringify(typeMapping)
      }
      data.taskTypeScope = Array.isArray(data.taskTypeScope)
        ? data.taskTypeScope.join(',')
        : data.taskTypeScope
      data.jobType = data.jobType[1]
      if (data.syncConf !== '{}') {
        data.syncConf = JSON.parse(data.syncConf)
        const obj = {}
        Object.keys(data.syncConf).forEach((f) => {
          const newValue = this.toSnakeCase(f, '.')
          obj[newValue] = data.syncConf[f]
          delete data.syncConf[f]
        })
        data.syncConf = JSON.stringify(obj)
      }
      if (data.jdbc && data.jdbc.length > 0) {
        data.jdbc.forEach((f) => {
          delete f.sortBySelectList
          delete f.instanceName
          delete f.name
        })
        const conf = {}
        data.jdbc.forEach((f) => {
          const item = data.mapping.filter((v) => f.tableName === v.tableName)
          conf[f.tableName] = item
        })
        data.mapping = JSON.stringify(conf)
      } else {
        data.mapping = JSON.stringify({})
      }
      data.batchConf = JSON.stringify(data.jdbc)
      removeValue.forEach((f) => delete form[f])
      const res = this.id
        ? await dataTaskconfedit(data)
        : await dataTaskconfadd(data)
      this.$message.success(res.msg)
      this.$router.push('/database/dataTaskconf')
      return false
    },
    handleClickStep(f) {
      if (this.active >= f || this.$route.query.id) {
        this.active = f
        return
      }
    }
  }
}
</script>
<style scoped lang="scss">
.app-container {
  width: 80%;
  margin: 0 auto;
  .buttonBox {
    margin: 40px auto;
    width: 87%;
    text-align: center;
  }

  .main {
    width: 100%;
    margin: 0 auto;
  }
}
</style>
